package com.sduept.nwld.dataserver.manager.cim;

import com.sduept.cim.model.core.Substation;
import com.sduept.cim.model.generation.HydroGeneratingUnit;
import com.sduept.cim.model.generation.ThermalGeneratingUnit;
import com.sduept.cim.model.wires.ACLineSegment;
import com.sduept.cim.model.wires.Breaker;
import com.sduept.cim.model.wires.BusbarSection;
import com.sduept.cim.model.wires.PowerTransformer;
import com.sduept.core.dao.SuperDAO;
import com.sduept.nwld.dataserver.model.edata.cim.bx.*;
import com.sduept.nwld.dataserver.util.CimUtils;
import com.sduept.utils.CharacterUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
@Slf4j
public class BxCimManager {
	@Autowired
	private SuperDAO dao;
	@Autowired
	private CimManager cimMan;
	
	public void saveBxSubstation(BxSubstation bean){
		dao.createOrUpdate(bean, BxSubstation.class);
	}
	public void saveBxACLineSegment(BxACLineSegment bean){
		dao.createOrUpdate(bean, BxACLineSegment.class);
	}
	public void saveBxBusbarsection(BxBusbarsection bean){
		dao.createOrUpdate(bean, BxBusbarsection.class);
	}
	public void saveBxBreaker(BxBreaker bean){
		dao.createOrUpdate(bean, BxBreaker.class);
	}
	public void saveBxPowertransformer(BxPowertransformer bean){
		dao.createOrUpdate(bean, BxPowertransformer.class);
	}
	public void saveBxCompensator(BxCompensator bean){
		dao.createOrUpdate(bean, BxCompensator.class);
	}
	public void saveBxHydrogeneratingunit(BxHydrogeneratingunit bean){
		dao.createOrUpdate(bean, BxHydrogeneratingunit.class);
	}
	public <T extends BxBaseEntity> List<? extends BxBaseEntity> getBxPrimaryEqupiment(boolean cimIdIsNull,Class<? extends BxBaseEntity> T){
		if(cimIdIsNull){
			return dao.findByCondition(T, "cimId is null");
		} else {
			return dao.findAll(T);
		}
	}
	public List<BxSubstation> getBxSubstation(boolean cimIdIsNull){
		if(cimIdIsNull){
			return dao.findByCondition(BxSubstation.class,"cimId is null");
		} else {
			return dao.findAll(BxSubstation.class);
		}
	}
	
	public BxSubstation findStationByCimId(String cimId){
		BxSubstation rtn = null;
		List<BxSubstation> ls = dao.findByCondition(BxSubstation.class,"cimId=?",cimId);
		if(ls.size() == 1){
			rtn = ls.get(0);
		}
		return rtn;
	}
	
	public String  relation500kVAcline(){
		int i_unfind = 0;
		dao.nativeUpdate("update t_bx_aclinesegment t1,t_bx_substation t2 set t1.cim_station_id = t2.cim_id where t1.stationid = t2.stationID;");
		List<ACLineSegment> cims = dao.findByCondition(ACLineSegment.class,"actualVoltage > 499");
		List<BxACLineSegment> bxs = dao.findAll(BxACLineSegment.class);
		StringBuilder errors = new StringBuilder();
		for (BxACLineSegment b : bxs) {
			String bxname = b.getMname();
			//去掉后面带断路器名称的数字如：大宝Ⅰ回5073
			bxname = bxname.replaceAll("//|[0-9]{1,4}$","");
			boolean find = false;
			for(ACLineSegment s : cims){
				if(CimUtils.lineNameMatching(bxname, s.getName())){
					b.setCimId(s.getId());
					b.setCimName(s.getName());
					find = true;
					break;
				}
			}
			if(!find){
				errors.append(b.getMname()+" 没有关联到CIM模型");
				errors.append("\r\n");
				i_unfind++;
			}
		}
		errors.append("总计："+bxs.size());
		errors.append("\r\n");
		errors.append("未关联："+i_unfind);
		errors.append("\r\n");
		errors.append("关联完毕");
		return errors.toString();
	}
	public String  relation500kVBreaker(){
		//首先执行更新cim变电站
		dao.nativeUpdate("update t_bx_breaker t1,t_bx_substation t2 "
				+ "set t1.cim_station_id = t2.cim_id "
				+ "where t1.stationid = t2.stationID;");
		
		List<Breaker> cims = cimMan.getAllBreakers();
		List<BxBreaker> bxs = dao.findAll(BxBreaker.class);
		StringBuilder errors = new StringBuilder();
		int i_unfind = 0;
		for (BxBreaker b : bxs) {
			boolean find = false;
			for(Breaker c : cims){
				if(org.apache.commons.lang3.StringUtils.isNotEmpty(b.getCimStationId()) 
						&& org.apache.commons.lang3.StringUtils.isNotEmpty(c.getSubId()) ){
					if(b.getCimStationId().equals(c.getSubId()) && CimUtils.breakerNameMatching2(b.getMname(), c.getName())){
						b.setCimId(c.getId());
						b.setCimName(c.getName());
						find = true;
						break;
					}
				}
			}
			if(!find){
				errors.append(b.getStationid() +" "+ b.getMname()+" 没有关联到CIM模型");
				errors.append("\r\n");
				i_unfind++;
			}
		}
		errors.append("总计："+bxs.size());
		errors.append("\r\n");
		errors.append("未关联："+i_unfind);
		errors.append("\r\n");
		errors.append("关联完毕");
		return errors.toString();
	}
	public String  relation500kVBusbar(){
		//首先执行更新cim变电站
		dao.nativeUpdate("update t_bx_busbarsection t1,t_bx_substation t2 "
				+ "set t1.cim_station_id = t2.cim_id "
				+ "where t1.stationid = t2.stationID;");
		int i_unfind = 0;
		List<BusbarSection> cims = cimMan.getAllBusbarSections();
		List<BxBusbarsection> bxs = dao.findAll(BxBusbarsection.class);
		StringBuilder errors = new StringBuilder();
		for (BxBusbarsection b : bxs) {
			boolean find = false;
			for(BusbarSection c : cims){
				if(org.apache.commons.lang3.StringUtils.isNotEmpty(b.getCimStationId()) 
						&& org.apache.commons.lang3.StringUtils.isNotEmpty(c.getSubId()) ){
					//相同的站，匹配相同的电压等级，相同的名称
					if(b.getCimStationId().equals(c.getSubId())){
						find = true;
						float bx_v = Float.valueOf(b.getMvoltage()).floatValue();
						//电压等级有可能在母线名字上体现，比如500kV1M,220kV1M
						float bname_v = CimUtils.getVoltageByString(b.getMname());
						float cname_v = CimUtils.getVoltageByString(c.getName());
						if( bx_v == c.getStandVoltagelevel()
								|| bname_v == cname_v 
								|| bname_v ==c.getStandVoltagelevel()
								|| cname_v == bx_v){
							find = true;
						} else {
							find =false;
						}
					}
					if(find){
						//有的cim中只是1M，2M，但是其他系统中是500kV母线1M
						if(CimUtils.busNameMatching(b.getMname(), c.getName()) 
								|| CimUtils.busNameSingleMatching(b.getMname(), c.getName()) ){
							b.setCimId(c.getId());
							b.setCimName(c.getName());
							find = true;
							break;
						} else {
							find = false;
						}
					}
				}
			}
			if(!find){
				errors.append(b.getStationid() +" "+ b.getMname()+" 没有关联到CIM模型");
				errors.append("\r\n");
				i_unfind ++;
			}
		}
		errors.append("总计："+bxs.size());
		errors.append("\r\n");
		errors.append("未关联："+i_unfind);
		errors.append("\r\n");
		errors.append("关联完毕");
		return errors.toString();
	}
	public String  relation500kVPowerTrans(){
		//首先执行更新cim变电站
		dao.nativeUpdate("update t_bx_powertransformer t1,t_bx_substation t2 "
				+ "set t1.cim_station_id = t2.cim_id "
				+ "where t1.stationid = t2.stationID;");
		int i_unfind = 0;
		List<PowerTransformer> cims = cimMan.getAllPowerTransformers();
		List<BxPowertransformer> bxs = dao.findAll(BxPowertransformer.class);
		StringBuilder errors = new StringBuilder();
		for (BxPowertransformer b : bxs) {
			boolean find = false;
			for(PowerTransformer c : cims){
				if(org.apache.commons.lang3.StringUtils.isNotEmpty(b.getCimStationId()) 
						&& org.apache.commons.lang3.StringUtils.isNotEmpty(c.getSubId()) ){
					//相同的站，匹配相同的电压等级，相同的名称
					if(b.getCimStationId().equals(c.getSubId()) 
							&& CimUtils.powerTransNameMatching(b.getMname(), c.getName())){
						b.setCimId(c.getId());
						b.setCimName(c.getName());
						find = true;
						break;
					}
				}
			}
			if(!find){
				errors.append(b.getStationid() +" "+ b.getMname()+" 没有关联到CIM模型");
				errors.append("\r\n");
				i_unfind++;
			}
		}
		errors.append("总计："+bxs.size());
		errors.append("\r\n");
		errors.append("未关联："+i_unfind);
		errors.append("\r\n");
		errors.append("关联完毕");
		return errors.toString();
	}
	public String relationSubstation(){
		List<Substation> cims = dao.findAll(Substation.class);
		List<BxSubstation> bxs = getBxSubstation(false);
		StringBuilder errors = new StringBuilder();
		int i_unfind = 0;
		for (BxSubstation b : bxs) {
			String sid = b.getMname();
			boolean find = false;
			sid = CharacterUtil.qj2bj(sid);
			for(Substation s : cims){
				//如果保信系统的站ID被CIM包含，例如500kV广南变---广南
				//CIM模型中有trans（变电站类型），hydro，thermal发电厂类型，有可能根据保信id会重复
				//例如 鸭溪 可找到两个 鸭溪电厂，500kV鸭溪变，要根据类型区分
				//保信只有名称可区分，包含电厂，水电等字的为电厂
				String cimname = CharacterUtil.qj2bj(s.getName());
				if(cimname.equals(sid) ||cimname.contains(sid)|| sid.contains(cimname)){
					b.setCimId(s.getId());
					b.setCimName(cimname);
					find = true;
					break;
				}else if(CharacterUtil.stringMatching(cimname, sid) == sid.length()){
					//开头就有厂的情况，会有“厂口站” 这种情况
					if(b.getMname().contains("电") || b.getMname().contains("厂")){
						if(!"trans".equals(s.getSubstationType()) || (cimname.contains(sid))){
							b.setCimId(s.getId());
							b.setCimName(cimname);
							find = true;
							break;
						} 
					} else {
						if("trans".equals(s.getSubstationType()) || "other".equals(s.getSubstationType())){
							b.setCimId(s.getId());
							b.setCimName(cimname);
							find = true;
							break;
						}
					}
					
				} else {
					if(CimUtils.stationNameMatching(cimname,b.getMname(),true)){
						b.setCimId(s.getId());
						b.setCimName(cimname);
						find = true;
						break;
					}
				}
			}
			if(!find){
				errors.append(b.getMname()+" 没有关联到CIM模型");
				errors.append("\r\n");
				i_unfind++;
			} else {
				dao.update(b, BxSubstation.class);
			}
		}
		errors.append("总计："+bxs.size());
		errors.append("\r\n");
		errors.append("未关联："+i_unfind);
		errors.append("\r\n");
		errors.append("关联完毕");
		return errors.toString();
	}
	public BxACLineSegment getBxACLineByMid(String mid){
		List<BxACLineSegment> list = dao.findByCondition(BxACLineSegment.class, "mid=?", mid);
		if(list!=null&&list.size()>0){
			return list.get(0);
		}
		return null;
	}
	
	public BxBreaker getBxBreakerById(String mid){
		List<BxBreaker> list = dao.findByCondition(BxBreaker.class, "mid=?", mid);
		if(list!=null&&list.size()>0){
			return list.get(0);
		}
		return null;
	}
	public BxBusbarsection getBxBusbarsectionById(String mid){
		List<BxBusbarsection> list = dao.findByCondition(BxBusbarsection.class, "mid=?", mid);
		if(list!=null&&list.size()>0){
			return list.get(0);
		}
		return null;
	}
	public BxCompensator getBxCompensatorById(String mid){
		List<BxCompensator> list = dao.findByCondition(BxCompensator.class, "mid=?", mid);
		if(list!=null&&list.size()>0){
			return list.get(0);
		}
		return null;
	}
	public BxPowertransformer getBxPowertransformerById(String mid){
		List<BxPowertransformer> list = dao.findByCondition(BxPowertransformer.class, "mid=?", mid);
		if(list!=null&&list.size()>0){
			return list.get(0);
		}
		return null;
	}
	public BxSubstation getBxSubstationById(String stationID){
		List<BxSubstation> list = dao.findByCondition(BxSubstation.class, "stationID=?", stationID);
		if(list!=null&&list.size()>0){
			return list.get(0);
		}
		return null;
	}
	
	public List<BxACLineSegment> listAllAclines(){
		return dao.findAll(BxACLineSegment.class);
	}
	public List<BxSubstation> listAllBxSubstations(){
		return dao.findAll(BxSubstation.class);
	}
	public List<BxPowertransformer> listAllTransformers(){
		return dao.findAll(BxPowertransformer.class);
	}
	public List<BxCompensator> listAllCompensators(){
		return dao.findAll(BxCompensator.class);
	}
	public List<BxBreaker> listAllBreakers(){
		return dao.findAll(BxBreaker.class);
	}
	public List<BxBusbarsection> listAllBxBusbarsections(){
		return dao.findAll(BxBusbarsection.class);
	}
	public List<BxHydrogeneratingunit> listAllBxUnits(){
		return dao.findAll(BxHydrogeneratingunit.class);
	}
	public String relationGenerating() {
		dao.nativeUpdate("update t_bx_hydrogeneratingunit t1,t_bx_substation t2 "
				+ "set t1.cim_station_id = t2.cim_id "
				+ "where t1.stationid = t2.stationID;");

		List<BxHydrogeneratingunit> bxGeneratings = dao
				.findAll(BxHydrogeneratingunit.class);
		List<HydroGeneratingUnit> hu = dao.findAll(HydroGeneratingUnit.class);
		List<ThermalGeneratingUnit> tu = dao
				.findAll(ThermalGeneratingUnit.class);
		for (BxHydrogeneratingunit bx : bxGeneratings) {
			for (HydroGeneratingUnit s : hu) {
				
				if ( s.getSubName().contains(bx.getStationid()) && sub(bx.getMname()).equals(sub(s.getName()))) {
					bx.setCimId(s.getId());
					bx.setCimName(s.getName());
					break;
				}else if(isContain(s.getSubName(),bx.getStationid()) &&  sub(bx.getMname()).equals(sub(s.getName()))){
					bx.setCimId(s.getId());
					bx.setCimName(s.getName());
					break;
				}else if(s.equals(hu.get(hu.size()-1))){
					for (ThermalGeneratingUnit u : tu) {
						if (u.getSubName().contains(bx.getStationid()) && sub(bx.getMname()).equals(sub(u.getName()))){
							bx.setCimId(u.getId());
							bx.setCimName(u.getName());
							break;
						}else if(isContain(u.getSubName(),bx.getStationid()) && sub(bx.getMname()).equals(sub(u.getName()))){
							bx.setCimId(u.getId());
							bx.setCimName(u.getName());
							break;
						}else if(u.equals(tu.get(tu.size()-1))){
							log.info("未匹配:"+bx.getStationid()+"  "+bx.getMname());
						}
					}
				}
			}
		}
		return null;
	}
	private String sub(String a){
		String regEx="[^0-9]";   
		Pattern   p   =   Pattern.compile(regEx);    
		a = a.replaceAll("500", "");
		Matcher   m   =   p.matcher(a); 
		return m.replaceAll("").trim() ;
	}
	private  boolean isContain(String s1,String s2){
		char [] stringArr = s2.toCharArray();
		int pos[]=new int[stringArr.length];
		for(int i=0;i<stringArr.length;i++){
			String c = String.valueOf(stringArr[i]);
			if(s1.contains(c)){
				pos[i]=s1.indexOf(c);
				if(i!=0){
					if(pos[i]-pos[i-1]<0){
						return false;
					}
				}
			}else{
				return false;
			}
		}
		return true;
	}
}
